package com.whh.utils;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.text.SimpleDateFormat;
import java.util.Calendar;

public class HexUtils extends StrUtils {

	/**
	 * hex字符串转换为Byte值
	 * @param String
	 * hexStr hex字符串，每个hex之间没有分隔符
	 * @return byte[]
	 */
	public static byte[] hexToBytes(String hexStr) {
		if(isBlank(hexStr)) return null;
		
		hexStr = hexStr.toUpperCase();
		int len = hexStr.length() / 2;
		char[] hexChars = hexStr.toCharArray();
		byte[] d = new byte[len];
		
		String digital = "0123456789ABCDEF";
		int temp ;
		for(int i=0; i<d.length; i++) {
			temp = digital.indexOf(hexChars[2*i])*16;
			temp += digital.indexOf(hexChars[2*i+1]);
			d[i]=(byte)(temp&0xff);
		}
		return d;
	}
	
	public static byte[] longToBytes(long num) {
		byte[] byteNum = new byte[8];
		for(int ix=0; ix<8; ++ix) {
			int offset = 64-(ix+1)*8;
			byteNum[ix] = (byte)((num>>offset)&0xff);
		}
		return byteNum;
	}
	public static long bytesToLong(byte[] byteNum) {
		long num = 0;
		for(int ix = 0; ix <8; ++ix) {
			num <<= 8;
			num |= (byteNum[ix] & 0xff);
		}
		return num;
	}
	public static String longToDateTime(long num) {
		Calendar c = Calendar.getInstance();
		c.setTimeInMillis(num * 1000L);
		
		SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String s = fmt.format(c.getTime());
		return s;
	}
	public static int bytesToInt(byte[] byteNum) {
		int r = (int)((int)(byteNum[0] & 0x00ff) | ((int)byteNum[1])<<8 & 0xff00);
		return r;
	}
	public static byte[] intToBytes(int num) {
		byte[] byteNum = new byte[4];
		for(int ix=0; ix<4; ++ix) {
			int offset = 32-(ix+1)*8;
			byteNum[ix] = (byte)((num>>offset)&0xff);
		}
		return byteNum;
	}
	public static byte intToByte(int num) {
		return (byte)(num & 0x000000ff);
	}
	public static byte strToByte(String str) {
		byte result = 0;
		if(str.length() < 8){
			result = Byte.parseByte(str,2);
		}else if(str.length() == 8 && str.startsWith("1")){
			byte temp = Byte.parseByte(str.substring(1, str.length()-1),2);
			result = (byte) (0 - temp);
		}
		return result;
	}
	public static int byteToInt(byte byteNum) {
		return byteNum >= 0 ? byteNum : (128 + (128 + byteNum));
	}
	public static float bytesToFloat(byte[] byteNum) {
		int num=byteNum[0];
		num &= 0xff;
		num |= ((long)byteNum[1] << 8);
		num &= 0xffff;
		num |= ((long)byteNum[2] << 16);
		num &= 0xffffff;
		num |= ((long)byteNum[3] << 24);
		return Float.intBitsToFloat(num);
	}
	public static byte[] floatToBtyes(float f) {
		int fbit = Float.floatToIntBits(f);
		byte[] b = new byte[4];
		for(int i=0; i<4; i++)
			b[i] = (byte)(fbit>>(24-i*8));
		int len = b.length;
		byte[] dest = new byte[len];
		System.arraycopy(b, 0, dest, 0, len);
		byte t;
		for(int i=0; i<len/2; ++i) {
			t = dest[i];
			dest[i] = dest[len-i-1];
			dest[len-i-1]=t;
		}
		return dest;
	}
	public static int hexToInt(String hexStr) {
		if(isBlank(hexStr)) return 0;
	
		byte[] d = hexToBytes(hexStr);
		int r = bytesToInt(d);
		return r;
	}
	public static byte[] getHeartBytes() {
		byte[] bytes = new byte[1024];
		ByteBuffer bb = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
		bb.put((byte)0x68);
		bb.put(new byte[2]);
		bb.put(new byte[16]);
		bb.put(new byte[1]);
		bb.put((byte)0xa1);
		bb.putInt(1);
		bb.putLong(System.currentTimeMillis()/1000);
		bb.putShort(1,(short)(bb.position()+3));
		int crc = getCrc16(bytes,bb.position());
		bb.put((byte)(crc%256));
		bb.put((byte)(crc/256%256));
		bb.put((byte)0x16);
		
		byte[] tmp = new byte[bb.position()];
		System.arraycopy(bytes, 0, tmp, 0, tmp.length);
		return tmp;
	}
	public static byte[] getUpdateBytes(byte sendOnSector,byte version,byte fileSize) {
		byte[] bytes = new byte[1024];
		ByteBuffer bb = ByteBuffer.wrap(bytes).order(ByteOrder.LITTLE_ENDIAN);
		bb.put((byte)0x68);
		bb.put(new byte[2]);
		bb.put(new byte[16]);
		bb.put(new byte[1]);
		bb.put((byte)0xa4);
		bb.putInt(1);
		bb.putLong(System.currentTimeMillis()/1000);
		bb.putShort(1,(short)(bb.position()+3));
		
		bb.put(sendOnSector);
		bb.put(version);
		bb.put((byte)(fileSize<<8));
		bb.put((byte)(fileSize&0xff));
		
		int crc = getCrc16(bytes,bb.position());
		bb.put((byte)(crc%256));
		bb.put((byte)(crc/256%256));
		bb.put((byte)0x16);
		
		byte[] tmp = new byte[bb.position()];
		System.arraycopy(bytes, 0, tmp, 0, tmp.length);
		return tmp;
	}
	public static int getCrc16(byte[] bytes, int len) {
		int crc = 0x0000ffff;
		for(int i=0; i<len; i++) {
			crc ^=((int)bytes[i]&0x000000ff);
			for(int j=0; j<8; j++) {
				if((crc&0x00000001)!=0) {
					crc >>=1;
					crc ^=0x0000a001;
				}else {
					crc >>=1;
				}
			}
		}
		return crc;
	}
	public static String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder("");
	    if (src == null || src.length <= 0) {
	      return null;
	    }
	    for (int i = 0; i < src.length; i++) {
	      int v = src[i] & 0xFF;
	      String hv = Integer.toHexString(v);
	      if (hv.length() < 2) {
	        stringBuilder.append(0);
	      }
	      stringBuilder.append(hv);
	    }
	    return stringBuilder.toString();
	}
	public static void main(String[] args) {
		//String hex = "ef2c71b29202f3e642f2abd8d518f367ec3fbf6a6a61beb678ae0c871ee368ac";
		//System.out.println(HexUtils.hexStr2Str(hex));
		
		/*long longNum = 1555546922;
		System.out.println("测试的long值为：" + longNum);

        byte[] long2Bytes = HexUtils.longToBytes(longNum);
        System.out.printf("long转行成bytes: ");
        for (int ix = 0; ix < long2Bytes.length; ++ix) {
            System.out.print(long2Bytes[ix] + " ");
        }
        System.out.println();*/
		//byte[] long2Bytes={42, -61, -73, 92, 0, 0, 0, 0};
		/*byte[] long2Bytes={0, 0, 0, 0, 92, -73, -61, 42};
        long bytes2Long = HexUtils.bytesToLong(long2Bytes);
        System.out.println("bytes转行成long: " + bytes2Long);*/
		/*long num = 1555546922;
		String datetime = HexUtils.longToDateTime(num);
        System.out.println("long转行成DateTime: " + datetime);*/
		/*String hex ="71B6";
		int r = hexToInt(hex);
		System.out.println("string转行成int: " + r);*/
		
		//byte[] bits={0, 0, -20, 66};
		
		//float r = HexUtils.bytesToFloat(bits);
		byte[] b = HexUtils.hexToBytes("7f7e");
		System.out.println(b[0]+" "+b[1]);
	}
}
